package com.kt.learn1

/**
 * Kotlin 作用域函数示例
 * 包括 let、run、with、apply、also 等作用域函数的使用和区别
 */

fun main() {
    // let 函数
    chapter1LetFunction()

    // run 函数
    chapter2RunFunction()

    // with 函数
    chapter3WithFunction()

    // apply 函数
    chapter4ApplyFunction()

    // also 函数
    chapter5AlsoFunction()

    // 作用域函数的对比
    chapter6ComparisonOfScopeFunctions()
}

// let 函数
fun chapter1LetFunction() {
    println("\n===== let 函数 =====")

    // 定义一个 nullable 变量
    val name: String? = "Alice"

    // 使用 let 函数处理非空值
    name?.let {
        println("Name: $it")
    } ?: run {
        println("Name is null")
    }

    // let 函数返回 lambda 表达式的返回值
    val length = name?.let { it.length } ?: 0
    println("Length of name: $length")
}

// run 函数
fun chapter2RunFunction() {
    println("\n===== run 函数 =====")

    // 使用 run 函数初始化对象
    val user = run {
        val tempUser = User("Alice", 30)
        tempUser.address = "123 Main St"
        tempUser
    }
    println(user)

    // 使用 run 函数处理 nullable 值
    val name: String? = "Bob"
    val nameLength = name?.run {
        "Length of name: ${this.length}"
    } ?: "Name is null"
    println(nameLength)
}

// with 函数
fun chapter3WithFunction() {
    println("\n===== with 函数 =====")

    // 定义一个用户对象
    val user = User("Alice", 30)

    // 使用 with 函数调用对象的多个方法
    with(user) {
        address = "123 Main St"
        println("Name: $name")
        println("Age: $age")
        println("Address: $address")
    }
}

// apply 函数
fun chapter4ApplyFunction() {
    println("\n===== apply 函数 =====")

    // 使用 apply 函数初始化对象
    val user = User("Alice", 30).apply {
        address = "123 Main St"
    }
    println(user)
}

// also 函数
fun chapter5AlsoFunction() {
    println("\n===== also 函数 =====")

    // 使用 also 函数进行日志记录
    val user = User("Alice", 30).also {
        println("Creating user: ${it.name}")
    }
    println(user)
}

// 作用域函数的对比
fun chapter6ComparisonOfScopeFunctions() {
    println("\n===== 作用域函数的对比 =====")

    // 定义一个用户对象
    val user = User("Alice", 30)

    // let: 主要用于处理非空值，返回 lambda 表达式的返回值
    val nameLengthLet = user.name.let { it.length }
    println("Name length using let: $nameLengthLet")

    // run: 用于执行代码块，返回 lambda 表达式的返回值
    val nameLengthRun = user.name.run { length }
    println("Name length using run: $nameLengthRun")

    // with: 用于调用对象的多个方法，返回 lambda 表达式的返回值
    val nameLengthWith = with(user.name) { length }
    println("Name length using with: $nameLengthWith")

    // apply: 用于初始化对象，返回对象本身
    user.apply {
        address = "123 Main St"
    }
    println("User after apply: $user")

    // also: 用于进行额外操作，返回对象本身
    user.also {
        println("User name: ${it.name}")
    }
    println("User after also: $user")
}

// 定义一个数据类
data class User(var name: String, var age: Int) {
    var address: String = ""
}